import math
import time
import random
import re
import json
import requests
import pandas as pd
from datetime import datetime


EXCHANGE_DICT = {"SSE": "m:10", "SZSE": "m:12"}

def option_value_analysis_em(exchange: str = "SSE") -> pd.DataFrame:

    if exchange not in EXCHANGE_DICT:
        raise ValueError("exchange 只能是 'SSE' 或 'SZSE'")

    fs = EXCHANGE_DICT[exchange]
    pz = 50
    base_url = (
        "https://push2.eastmoney.com/api/qt/clist/get?"
        "fid=f301&po=1&np=1&fltt=2&invt=2"
        "&ut=8dec03ba335b81bf4ebdf7b29ec27d15"
        "&fields=f1,f2,f3,f12,f13,f14,f298,f299,f249,f300,f330,f331,f332,f333,f334,f335,f336,f301,f152"
        f"&fs={fs}&pz={pz}&pn={{page}}"
    )
    headers = {
        "Referer": "https://data.eastmoney.com/other/valueAnal.html",
        "User-Agent": (
            "Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
            "AppleWebKit/537.36 (KHTML, like Gecko) "
            "Chrome/137.0.0.0 Safari/537.36"
        ),
    }

    session = requests.Session()
    resp = session.get(base_url.format(page=1), headers=headers, timeout=30)
    match = re.search(r"\{.*\}\}$", resp.text)
    if not match:
        raise ValueError("未找到有效 JSON 数据")
    js = json.loads(match.group())
    total = js["data"]["total"]
    pages = math.ceil(total / pz)

    data = js["data"]["diff"]

    for page in range(2, pages + 1):
        resp = session.get(base_url.format(page=page), headers=headers, timeout=30)
        match = re.search(r"\{.*\}\}$", resp.text)
        if not match:
            continue
        js = json.loads(match.group())
        data.extend(js["data"]["diff"])
        time.sleep(3 + random.random() * 0.2)

    temp_df = pd.DataFrame(data)
    # print(f"DataFrame 列数: {len(temp_df.columns)}")  # 保留调试信息
    temp_df.columns = [
        # f1, f2, f3, f12, f13, f14, f152, f249, f298, f299, f300, f301, f330, f331, f332, f333, f334, f335, f336
        "id",  # f1
        "最新价",  # f2
        "涨幅",  # f3
        "期权代码",  # f12
        "f13",  # f13
        "期权名称",  # f14
        "f152",
        "隐含波动率",  # f249
        "时间价值",  # f298
        "内在价值",  # f299
        "理论价格",  # f300
        "到期日",  # f301
        "f330",  # f330
        "标的代码",  # f331
        "f332",  # f332
        "标的名称",  # f333
        "标的最新价",  # f334
        "标的涨幅",  # f335
        "标的近一年波动率",  # f336
    ]
    temp_df = temp_df[
        [
            "期权代码",
            "期权名称",
            "最新价",
            "时间价值",
            "内在价值",
            "隐含波动率",
            "理论价格",
            "标的代码",
            "标的名称",
            "标的最新价",
            "标的近一年波动率",
            "到期日",
        ]
    ]
    temp_df["最新价"] = round(pd.to_numeric(temp_df["最新价"], errors="coerce"), 4)
    temp_df["时间价值"] = pd.to_numeric(temp_df["时间价值"], errors="coerce")
    temp_df["内在价值"] = pd.to_numeric(temp_df["内在价值"], errors="coerce")
    temp_df["隐含波动率"] = pd.to_numeric(temp_df["隐含波动率"], errors="coerce")
    temp_df["理论价格"] = pd.to_numeric(temp_df["理论价格"], errors="coerce")
    temp_df["标的最新价"] = pd.to_numeric(temp_df["标的最新价"], errors="coerce")
    temp_df["标的近一年波动率"] = pd.to_numeric(
        temp_df["标的近一年波动率"], errors="coerce"
    )
    temp_df["到期日"] = pd.to_datetime(
        temp_df["到期日"].astype(str), errors="coerce"
    ).dt.date
    return temp_df


def fetch_all_option_value() :
    print(f"start fetch value ...")
    df_sse = option_value_analysis_em("SSE")
    print(f"SSE end")
    # print(df_sse)
    time.sleep(3)  # 防止请求过快
    df_szse = option_value_analysis_em("SZSE")
    print(f"SZSE end")
    # print(df_szse)
    combined_df = pd.concat([df_sse, df_szse], ignore_index=True)
    return combined_df

if __name__ == "__main__":
    filename = 'option_value_analysis_em_origin.csv'

    combined_df = fetch_all_option_value()
    combined_df.to_csv(filename, index=False, encoding='utf-8-sig')

    # combined_df = pd.read_csv(filename)
